
import json
import time
from flask import Flask
from flask import request
from flask import jsonify
from db_method import DataBaseMethod
from util import send_mqtt_message
from setting import *
import os
import logging


logging.basicConfig(level = logging.INFO,format = '%(asctime)s - %(name)s - %(levelname)s - %(message)s')

logger = logging.getLogger(__name__)


app = Flask(__name__)


@app.route('/get_cabinet_heartbeat_by_id') # 获取柜子当前最后一次心跳
def get_cabinet_heartbeat_by_id():

    cabinet_id = request.args.get('cabinet_id')

    result = DataBaseMethod().get_cabinet_heartbeat_by_id(cabinet_id)

    return jsonify({
        'status': 1,
        'errorCode': None,
        'errorMsg': None,
        'resultBody': result,
    })


@app.route('/open_door', methods = ["POST"]) # open door
def open_door():

    mac = request.form.get('mac')
    orderid = request.form.get('orderid')

    if not (mac and orderid):

        return jsonify({
            'status': -1,
            'errorCode': 1000,
            'errorMsg': "缺少参数",
            'resultBody': None,
        })
    
    cabinet_info = DataBaseMethod().get_cabinet_info_by_mac(mac)


    if not cabinet_info:

        return jsonify({
            'status': -1,
            'errorCode': 1001,
            'errorMsg': "没找到此设备或权限不够",
            'resultBody': None,
        })
    
    cabinet_id = cabinet_info['id']

    last_door_task_status = DataBaseMethod().get_last_door_task_status(cabinet_id)

    if last_door_task_status != "结束":
    
        cabinet_status = DataBaseMethod().get_cabinet_status(cabinet_id)["resultBody"]

        if cabinet_status == "盘点结束":

            return jsonify({
                'status': -1,
                'errorCode': 1002,
                'errorMsg': "设备正在执行其他任务:{}".format("正在同步盘点数据"),
                'resultBody': None,
            })

        else:

            return jsonify({
                'status': -1,
                'errorCode': 1002,
                'errorMsg': "设备正在执行其他任务:{}".format(cabinet_status),
                'resultBody': None,
            })
    

    DataBaseMethod().insert_door_task_by_cabinet_id({"orderid": orderid, "cabinet_id": cabinet_id}) # 插入开门任务到数据库

    topic = "rfid_cabinet/rx/{}".format(mac)
    # topic = "rfid_cabinet/rx/620790426a0e"

    message = {

        "task_type": "开门",
        "task_data": {
            "orderid": orderid
        }
    }

    # 下发开门命令
    send_mqtt_message(broker_address=BROKER_ADDRESS, broker_port=BROKER_PORT, topic=topic, message=json.dumps(message))

    return jsonify({
        'status': 1,
        'errorCode': None,
        'errorMsg': None,
        'resultBody': "success",
    })

@app.route('/cabinet_status') # 设备新动态
def cabinet_status():

    cabinet_id = request.args.get('cabinet_id')

    result = DataBaseMethod().get_cabinet_status(cabinet_id)

    return jsonify(result)

@app.route('/cabinet_status_by_mac') # 设备新动态
def cabinet_status_by_mac():

    mac = request.args.get('mac')

    result = DataBaseMethod().get_cabinet_status_by_mac_api(mac)

    return jsonify(result)



@app.route('/get_esp_list_by_cabinet_id') # 查询柜体内部当前标签
def get_esp_list_by_cabinet_id():

    cabinet_id = request.args.get('cabinet_id')

    result = DataBaseMethod().get_esp_list_by_cabinet_id(cabinet_id)

    return jsonify({
        'status': 1,
        'errorCode': None,
        'errorMsg': None,
        'resultBody': result,
    })


@app.route('/get_esp_list_by_cabinet_mac') # 查询柜体内部当前标签
def get_esp_list_by_cabinet_mac():

    mac = request.args.get('mac')

    result = DataBaseMethod().get_esp_list_by_cabinet_mac(mac)

    return jsonify({
        'status': 1,
        'errorCode': None,
        'errorMsg': None,
        'resultBody': result,
    })



@app.route('/get_esp_difference_by_door_orderid') # 获取指定开门任务盘点esp列表和上次结束状态开门esp列表的差异
def get_esp_difference_by_door_orderid():

    orderid = request.args.get('orderid')

    result = DataBaseMethod().get_esp_difference_by_door_orderid(orderid)

    return jsonify(result)



@app.route('/get_all_cabinet') # 查询柜体列表
def get_all_cabinet():

    page = request.args.get('page', 1, type=int)
    per_page = request.args.get('per_page', 10, type=int)
    sort = request.args.get('sort', "asc")

    result = DataBaseMethod().get_all_cabinet(page, per_page, sort)

    return jsonify({
        'status': 1,
        'errorCode': None,
        'errorMsg': None,
        'resultBody': result,
    })

@app.route('/get_all_esp_tags') # 查询esp标签
def get_all_esp_tags():

    page = request.args.get('page', 1, type=int)
    per_page = request.args.get('per_page', 10, type=int)
    sort = request.args.get('sort', "asc")

    result = DataBaseMethod().get_all_esp_tags(page, per_page, sort)

    return jsonify({
        'status': 1,
        'errorCode': None,
        'errorMsg': None,
        'resultBody': result,
    })

@app.route('/insert_esp_tags', methods=["POST"]) # 批量插入esp标签
def insert_esp_tags():

    tags = request.form.get("tags")

    if not tags:

        return jsonify({
            'status': -1,
            'errorCode': 1000,
            'errorMsg': "缺少参数",
            'resultBody': None,
        })
    
    try:

        DataBaseMethod().insert_esp_tags(json.loads(tags))

    except Exception as e:

        return jsonify({
            'status': -1,
            'errorCode': 1000,
            'errorMsg': str(e),
            'resultBody': None,
        })
    
    else:

        return jsonify({
            'status': 1,
            'errorCode': None,
            'errorMsg': None,
            'resultBody': "添加成功",
        })
    

@app.route('/insert_settlement_callback_route_info', methods=["POST"]) # 插入回调路由链接
def insert_settlement_callback_route_info():

    route_url = request.form.get("route_url")

    if not route_url:

        return jsonify({
            'status': -1,
            'errorCode': 1000,
            'errorMsg': "缺少参数",
            'resultBody': None,
        })
    
    DataBaseMethod().insert_settlement_callback_route_info(route_url)

    return jsonify({
        'status': 1,
        'errorCode': None,
        'errorMsg': None,
        'resultBody': "添加成功",
    })
    
@app.route('/get_settlement_callback_route_info') # 查询回调路由链接
def get_settlement_callback_info():

    
    result = DataBaseMethod().get_settlement_callback_info()

    return jsonify({
        'status': 1,
        'errorCode': None,
        'errorMsg': None,
        'resultBody': result,
    })


@app.route('/shopping_video_submission', methods=['POST'])
def shopping_video_submission():
    if 'file' not in request.files:
        
        return jsonify({
            'status': -1,
            'errorCode': 3000,
            'errorMsg': 'No file part in the request.',
            'resultBody': None,
        })

    md5 = request.form.get("md5")

    if not md5:

        return jsonify({
            'status': -1,
            'errorCode': 1000,
            'errorMsg': 'lost arg md5',
            'resultBody': None,
        })


    file = request.files['file']
    if file.filename == '':

        return jsonify({
            'status': -1,
            'errorCode': 3001,
            'errorMsg': 'No selected file.',
            'resultBody': None,
        })
    
    DataBaseMethod().insert_upload_video_status({"orderid": file.filename, "md5": md5})


    logger.info("save start: {}".format(time.time()))

    # 处理上传文件
    file.save('/media/rfid_cabinet/' + file.filename)

    logger.info("save end: {}".format(time.time()))
    
    return jsonify({
        'status': 1,
        'errorCode': None,
        'errorMsg': None,
        'resultBody': 'File uploaded successfully.',
    })



@app.route('/get_online_status_by_mac_list', methods=["POST"]) # 获取设备最新在线状态
def get_online_status_by_mac_list():

    mac_list = request.form.get("mac_list")

    if not mac_list:

        return jsonify({
            'status': -1,
            'errorCode': 1000,
            'errorMsg': "缺少参数",
            'resultBody': None,
        })

    mac_list = json.loads(mac_list)

    return jsonify({
        'status': 1,
        'errorCode': None,
        'errorMsg': None,
        'resultBody': DataBaseMethod().get_online_status_by_mac_list(mac_list),
    })


@app.route('/get_latest_status_by_mac_list', methods=["POST"]) # 获取设备最新在线状态
def get_latest_status_by_mac_list():

    mac_list = request.form.get("mac_list")

    if not mac_list:

        return jsonify({
            'status': -1,
            'errorCode': 1000,
            'errorMsg': "缺少参数",
            'resultBody': None,
        })
    
    mac_list = json.loads(mac_list)

    print("mac_list: {}".format(mac_list))

    return jsonify({
        'status': 1,
        'errorCode': None,
        'errorMsg': None,
        'resultBody': DataBaseMethod().get_latest_status_by_mac_list(mac_list),
    })

@app.route('/get_cabinet_abnormal_status_by_mac_list', methods=["POST"]) # 获取设备最新在线状态
def get_cabinet_abnormal_status_by_mac_list():

    mac_list = request.form.get("mac_list")

    if not mac_list:

        return jsonify({
            'status': -1,
            'errorCode': 1000,
            'errorMsg': "缺少参数",
            'resultBody': None,
        })

    mac_list = json.loads(mac_list)

    return jsonify({
        'status': 1,
        'errorCode': None,
        'errorMsg': None,
        'resultBody': DataBaseMethod().get_cabinet_abnormal_by_mac_list(mac_list),
    })

@app.route('/send_upload_video_command') # 下发上传视频指令
def send_upload_video_command():

    orderid = request.args.get("orderid")

    if not orderid:

        return jsonify({
            'status': -1,
            'errorCode': 1000,
            'errorMsg': "缺少参数",
            'resultBody': None,
        })
    
    cabinet_mac = DataBaseMethod().get_cabinet_mac_by_orderid(orderid)

    if cabinet_mac == "订单未找到对应的购物柜":

        return jsonify({
            'status': -1,
            'errorCode': 1004,
            'errorMsg': cabinet_mac,
            'resultBody': None
        }) 

    topic = "rfid_cabinet/rx/{}".format(cabinet_mac)
    # topic = "rfid_cabinet/rx/620790426a0e"

    message = {
        "task_type": "上传购物视频",
        "task_data": {
            "orderid": orderid
        }

    }

    try:

        send_mqtt_message(broker_address=BROKER_ADDRESS, broker_port=BROKER_PORT, topic=topic, message=json.dumps(message))

    except Exception as e:

        return jsonify({
            'status': -1,
            'errorCode': 1003,
            'errorMsg': "指令下发失败",
            'resultBody': str(e),
        })
    
    else:

        return jsonify({
            'status': 1,
            'errorCode': None,
            'errorMsg': None,
            'resultBody': "指令下发成功",
        })
    

@app.route('/send_set_ad_media_volum_command') # 下发上传视频音量指令 会重启视频服务
def send_set_ad_media_volum_command():

    cabinet_mac = request.args.get("cabinet_mac")
    ad_volume = request.args.get("ad_volume")

    if not (ad_volume and cabinet_mac):

        return jsonify({
            'status': -1,
            'errorCode': 1000,
            'errorMsg': "缺少参数",
            'resultBody': None,
        })
    

    topic = "rfid_cabinet/rx/{}".format(cabinet_mac)
    # topic = "rfid_cabinet/rx/620790426a0e"

    message = {
        "task_type": "设置广告音量",
        "task_data": {
            "ad_volume": ad_volume
        }

    }

    try:

        send_mqtt_message(broker_address=BROKER_ADDRESS, broker_port=BROKER_PORT, topic=topic, message=json.dumps(message))

    except Exception as e:

        return jsonify({
            'status': -1,
            'errorCode': 1003,
            'errorMsg': "指令下发失败",
            'resultBody': str(e),
        })
    
    else:

        return jsonify({
            'status': 1,
            'errorCode': None,
            'errorMsg': None,
            'resultBody': "指令下发成功",
        })
    
@app.route('/send_inventory_command') # 下发盘点指令
def send_inventory_command():

    cabinet_mac = request.args.get("cabinet_mac")

    if not cabinet_mac:

        return jsonify({
            'status': -1,
            'errorCode': 1000,
            'errorMsg': "缺少参数",
            'resultBody': None,
        })
    

    topic = "rfid_cabinet/rx/{}".format(cabinet_mac)
    # topic = "rfid_cabinet/rx/620790426a0e"

    orderid = str( time.time() )

    cabinet_info = DataBaseMethod().get_cabinet_info_by_mac(cabinet_mac)

    if not cabinet_info:

        return jsonify({
            'status': -1,
            'errorCode': 1001,
            'errorMsg': "没找到此设备或权限不够",
            'resultBody': None,
        })
    
    cabinet_id = cabinet_info['id']

    last_door_task_status = DataBaseMethod().get_last_door_task_status(cabinet_id)

    if last_door_task_status != "结束":
    
        cabinet_status = DataBaseMethod().get_cabinet_status(cabinet_id)["resultBody"]

        if cabinet_status == "盘点结束":

            return jsonify({
                'status': -1,
                'errorCode': 1002,
                'errorMsg': "设备正在执行其他任务:{}".format("正在同步盘点数据"),
                'resultBody': None,
            })

        else:

            return jsonify({
                'status': -1,
                'errorCode': 1002,
                'errorMsg': "设备正在执行其他任务:{}".format(cabinet_status),
                'resultBody': None,
            })

    DataBaseMethod().insert_door_task_by_cabinet_id({"orderid": orderid, "cabinet_id": cabinet_id})

    # 下发盘点
    message = {
        "task_type": "重新盘点",
        "task_data": {

            "orderid": orderid
        }
    }

    try:

        send_mqtt_message(broker_address=BROKER_ADDRESS, broker_port=BROKER_PORT, topic=topic, message=json.dumps(message))

    except Exception as e:

        return jsonify({
            'status': -1,
            'errorCode': 1003,
            'errorMsg': "指令下发失败",
            'resultBody': str(e),
        })
    
    else:

        return jsonify({
            'status': 1,
            'errorCode': None,
            'errorMsg': None,
            'resultBody': "指令下发成功",
        })
    

@app.route('/send_set_ad_media_command') # 下发播放指定广告指令 会重启视频服务
def send_set_ad_media_command():

    cabinet_mac = request.args.get("cabinet_mac")
    ad_volume = request.args.get("ad_volume")
    ad_media_url = request.args.get("ad_media_url")

    if ad_volume == None:

        ad_volume = 1.0

    if not (ad_media_url and cabinet_mac):

        return jsonify({
            'status': -1,
            'errorCode': 1000,
            'errorMsg': "缺少参数",
            'resultBody': None,
        })
    

    topic = "rfid_cabinet/rx/{}".format(cabinet_mac)
    # topic = "rfid_cabinet/rx/620790426a0e"

    message = {

        "task_type": "设置广告",
        "task_data": {
            "ad_media_url": ad_media_url,
            "ad_volurm": ad_volume
        }
    }

    try:

        send_mqtt_message(broker_address=BROKER_ADDRESS, broker_port=BROKER_PORT, topic=topic, message=json.dumps(message))

    except Exception as e:

        return jsonify({
            'status': -1,
            'errorCode': 1003,
            'errorMsg': "指令下发失败",
            'resultBody': str(e),
        })
    
    else:

        return jsonify({
            'status': 1,
            'errorCode': None,
            'errorMsg': None,
            'resultBody': "指令下发成功",
        })
    

@app.route('/get_cabinet_screen_ui_args') # 获取当前设备头UI配置参数
def get_cabinet_screen_ui_args():

    if os.path.exists("/root/.cabinet_screen_ui_args"):

        with open("/root/.cabinet_screen_ui_args", "r", encoding="utf-8") as f:

            ui_args = json.loads(f.read())

    else:

        ui_args = {

            "top_color": "#2c5cb3",
            "mid_color": "#3399FF",
            "title_size": 28,
            "goods_size": 14,
            "bottom_status_size": 18,
            "bottom_total_size": 20,
            "goods_font_color": "red",
            "title_font_color": "white",
            "bottom_status_color": "white",
            "bottom_total_color": "white",

            "top_weight": "2",
            "mid_weight": "6",
            "bottom_weight": "2",
            
        }

    return jsonify({
        'status': 1,
        'errorCode': None,
        'errorMsg': None,
        'resultBody': ui_args,
        
    })


    

@app.route('/send_ui_color_command') # 下发UI配置参数
def send_ui_color_command():

    cabinet_mac = request.args.get("cabinet_mac")
    top_color = request.args.get("top_color")
    mid_color = request.args.get("mid_color")
    title_size = request.args.get("title_size")
    goods_size = request.args.get("goods_size")
    bottom_status_size = request.args.get("bottom_status_size")
    bottom_total_size = request.args.get("bottom_total_size")
    goods_font_color = request.args.get("goods_font_color")
    title_font_color = request.args.get("title_font_color")
    bottom_status_color = request.args.get("bottom_status_color")
    bottom_total_color = request.args.get("bottom_total_color")

    top_weight = request.args.get("top_weight")
    mid_weight = request.args.get("mid_weight")
    bottom_weight = request.args.get("bottom_weight")


    if not (top_color and cabinet_mac and mid_color):

        return jsonify({
            'status': -1,
            'errorCode': 1000,
            'errorMsg': "缺少参数",
            'resultBody': None,
            
        })
    

    topic = "rfid_cabinet/rx/{}".format(cabinet_mac)
    # topic = "rfid_cabinet/rx/620790426a0e"

    message = {

        "task_type": "设置背景颜色",
        "task_data": {
            "top_color": top_color,
            "mid_color": mid_color,
            "title_size": title_size if title_size is not None else 28,
            "goods_size": goods_size if title_size is not None else 14,
            "bottom_status_size": bottom_status_size if title_size is not None else 18,
            "bottom_total_size": bottom_total_size if title_size is not None else 20,
            "goods_font_color": goods_font_color if title_size is not None else "black",
            "title_font_color": title_font_color if title_size is not None else "white",
            "bottom_status_color": bottom_status_color if title_size is not None else "white",
            "bottom_total_color": bottom_total_color if title_size is not None else "white",

            "top_weight": top_weight if title_size is not None else "2",
            "mid_weight": mid_weight if title_size is not None else "6",
            "bottom_weight": bottom_weight if title_size is not None else "2",
        }
    }

    try:

        send_mqtt_message(broker_address=BROKER_ADDRESS, broker_port=BROKER_PORT, topic=topic, message=json.dumps(message))

    except Exception as e:

        return jsonify({
            'status': -1,
            'errorCode': 1003,
            'errorMsg': "指令下发失败",
            'resultBody': str(e),
        })
    
    else:

        with open("/root/.cabinet_screen_ui_args", 'w') as f:

            f.write(json.dumps(message))

        return jsonify({
            'status': 1,
            'errorCode': None,
            'errorMsg': None,
            'resultBody': "指令下发成功",
        })

################测试链接#####################

@app.route('/open_door______') # open door
def open_door______():

    mac = request.args.get('mac')
    orderid = str(time.time())

    if not (mac and orderid):

        return jsonify({
            'status': -1,
            'errorCode': 1000,
            'errorMsg': "缺少参数",
            'resultBody': None,
        })
    
    cabinet_info = DataBaseMethod().get_cabinet_info_by_mac(mac)


    if not cabinet_info:

        return jsonify({
            'status': -1,
            'errorCode': 1001,
            'errorMsg': "没找到此设备或权限不够",
            'resultBody': None,
        })
    
    cabinet_id = cabinet_info['id']

    last_door_task_status = DataBaseMethod().get_last_door_task_status(cabinet_id)

    if last_door_task_status != "结束":
    
        cabinet_status = DataBaseMethod().get_cabinet_status(cabinet_id)["resultBody"]

        if cabinet_status == "盘点结束":

            return jsonify({
                'status': -1,
                'errorCode': 1002,
                'errorMsg': "设备正在执行其他任务:{}".format("正在同步盘点数据"),
                'resultBody': None,
            })

        else:

            return jsonify({
                'status': -1,
                'errorCode': 1002,
                'errorMsg': "设备正在执行其他任务:{}".format(cabinet_status),
                'resultBody': None,
            })
    

    DataBaseMethod().insert_door_task_by_cabinet_id({"orderid": orderid, "cabinet_id": cabinet_id}) # 插入开门任务到数据库

    topic = "rfid_cabinet/rx/{}".format(mac)
    # topic = "rfid_cabinet/rx/620790426a0e"

    message = {

        "task_type": "开门",
        "task_data": {
            "orderid": orderid
        }
    }

    # 下发开门命令
    send_mqtt_message(broker_address=BROKER_ADDRESS, broker_port=BROKER_PORT, topic=topic, message=json.dumps(message))

    return jsonify({
        'status': 1,
        'errorCode': None,
        'errorMsg': None,
        'resultBody': "success",
    })


@app.route('/update_tag_status_______') # open door
def update_tag_status_______():

    DataBaseMethod().test_update_esp_tag_status()

    return jsonify({
        'status': 1,
        'errorCode': None,
        'errorMsg': None,
        'resultBody': "success",
    })



    
if __name__ == '__main__':

    app.run(debug=True, host="0.0.0.0", port=8020)